/*
 * @(#)gray2.c	1.15 06/10/10
 *
 * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 only, as published by the Free Software Foundation. 
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License version 2 for more details (a copy is
 * included at /legal/license.txt). 
 * 
 * You should have received a copy of the GNU General Public License
 * version 2 along with this work; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA 
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 or visit www.sun.com if you need additional
 * information or have any questions. 
 *
 */
#include "Xheaders.h"
#include "common.h"

extern unsigned short ntsc_gray_value[3][256];
extern unsigned char img_grays[256];
extern unsigned char img_bwgamma[256];
extern double pow(double, double);

/* this is corrected for gamma = 1.67 (a compromise) */
static XColor gray2_cells[16] = {
    {0,  0x0000, 0x0000, 0x0000, DoRed | DoGreen | DoBlue, 0},
    {1,  0x7777, 0x7777, 0x7777, DoRed | DoGreen | DoBlue, 0},
    {2,  0xcccc, 0xcccc, 0xcccc, DoRed | DoGreen | DoBlue, 0},
    {3,  0xffff, 0xffff, 0xffff, DoRed | DoGreen | DoBlue, 0},
};

static void Gray2_pixel2RGB(unsigned int pixel, int *r, int *g, int *b) {
    if ((pixel > 3) || (mapped_pixels[pixel] != pixel)) {
	int i = 3;
	while (--i > 0) {
	    if (mapped_pixels[i] == pixel) {
		break;
	    }
	}
	pixel = i;
    }

    /* because gamma correction is pre-computed, we need to lie! */
    *r = 0x55 * pixel;
    *g = 0x55 * pixel;
    *b = 0x55 * pixel;
}

static unsigned int Gray2_RGB2Pixel(int r, int g, int b) {
    unsigned int gray = ntsc_gray_value[0][r & 0xff]
	              + ntsc_gray_value[1][g & 0xff]
	              + ntsc_gray_value[2][b & 0xff];

    return gray2_cells[gray >> 14].pixel;
}

static unsigned int Gray2_jRGB2Pixel(unsigned int RGB, int gamma_corr) {
    unsigned int gray = ntsc_gray_value[0][(RGB >> 16) & 0xff]
	              + ntsc_gray_value[1][(RGB >> 8)  & 0xff]
	              + ntsc_gray_value[2][(RGB >> 0)  & 0xff];

    /* the available grays are already gamma corrected */
    return gray2_cells[gray >> 14].pixel;
}

void setupGray2(Colormap cmap, unsigned long pixels[],
		 XVisualInfo *visInfo) {
    int i;

    assert(NATIVE_LOCK_HELD());

    if ((visInfo->class == PseudoColor) || (visInfo->class == GrayScale)) {
	for (i = 0; i < 4; ++i) {
	    gray2_cells[i].pixel = pixels[i];
	}
	XStoreColors(awt_display, awt_cmap, gray2_cells, 4);
    } else {
	for (i = 0; i < 4; ++i) {
	    XAllocColor(awt_display, awt_cmap, gray2_cells + i);
	}
    }

    for (i = 0; i < 256; ++i) {
	img_bwgamma[i] = (int)(255 * pow(i/255.0, 0.8));
	img_grays[i] = gray2_cells[i >> 6].pixel;
    }

    pixel2RGB  = Gray2_pixel2RGB;
    RGB2Pixel  = Gray2_RGB2Pixel;
    jRGB2Pixel = Gray2_jRGB2Pixel;
    numColors  = 4;
    grayscale  = 1;
}

unsigned short ntsc_gray_value[3][256] = {
    {
	0,77,154,231,308,385,462,539,616,693,771,848,925,1002,1079,1156,
	1233,1310,1387,1464,1542,1619,1696,1773,1850,1927,2004,2081,
	2158,2235,2313,2390,2467,2544,2621,2698,2775,2852,2929,3006,
	3084,3161,3238,3315,3392,3469,3546,3623,3700,3777,3855,3932,
	4009,4086,4163,4240,4317,4394,4471,4548,4626,4703,4780,4857,
	4934,5011,5088,5165,5242,5319,5397,5474,5551,5628,5705,5782,
	5859,5936,6013,6090,6168,6245,6322,6399,6476,6553,6630,6707,
	6784,6861,6939,7016,7093,7170,7247,7324,7401,7478,7555,7632,
	7710,7787,7864,7941,8018,8095,8172,8249,8326,8403,8481,8558,
	8635,8712,8789,8866,8943,9020,9097,9174,9252,9329,9406,9483,
	9560,9637,9714,9791,9868,9945,10023,10100,10177,10254,10331,
	10408,10485,10562,10639,10716,10794,10871,10948,11025,11102,
	11179,11256,11333,11410,11487,11565,11642,11719,11796,11873,
	11950,12027,12104,12181,12258,12336,12413,12490,12567,12644,
	12721,12798,12875,12952,13029,13107,13184,13261,13338,13415,
	13492,13569,13646,13723,13800,13878,13955,14032,14109,14186,
	14263,14340,14417,14494,14571,14649,14726,14803,14880,14957,
	15034,15111,15188,15265,15342,15420,15497,15574,15651,15728,
	15805,15882,15959,16036,16113,16191,16268,16345,16422,16499,
	16576,16653,16730,16807,16884,16962,17039,17116,17193,17270,
	17347,17424,17501,17578,17655,17733,17810,17887,17964,18041,
	18118,18195,18272,18349,18426,18504,18581,18658,18735,18812,
	18889,18966,19043,19120,19197,19275,19352,19429,19506,19583,
	19660
    },
    {
	0,151,303,454,606,758,909,1061,1213,1364,1516,1667,1819,1971,
	2122,2274,2426,2577,2729,2880,3032,3184,3335,3487,3639,3790,
	3942,4094,4245,4397,4548,4700,4852,5003,5155,5307,5458,5610,
	5761,5913,6065,6216,6368,6520,6671,6823,6974,7126,7278,7429,
	7581,7733,7884,8036,8188,8339,8491,8642,8794,8946,9097,9249,
	9401,9552,9704,9855,10007,10159,10310,10462,10614,10765,10917,
	11068,11220,11372,11523,11675,11827,11978,12130,12282,12433,
	12585,12736,12888,13040,13191,13343,13495,13646,13798,13949,
	14101,14253,14404,14556,14708,14859,15011,15163,15314,15466,
	15617,15769,15921,16072,16224,16376,16527,16679,16830,16982,
	17134,17285,17437,17589,17740,17892,18043,18195,18347,18498,
	18650,18802,18953,19105,19257,19408,19560,19711,19863,20015,
	20166,20318,20470,20621,20773,20924,21076,21228,21379,21531,
	21683,21834,21986,22137,22289,22441,22592,22744,22896,23047,
	23199,23351,23502,23654,23805,23957,24109,24260,24412,24564,
	24715,24867,25018,25170,25322,25473,25625,25777,25928,26080,
	26231,26383,26535,26686,26838,26990,27141,27293,27445,27596,
	27748,27899,28051,28203,28354,28506,28658,28809,28961,29112,
	29264,29416,29567,29719,29871,30022,30174,30326,30477,30629,
	30780,30932,31084,31235,31387,31539,31690,31842,31993,32145,
	32297,32448,32600,32752,32903,33055,33206,33358,33510,33661,
	33813,33965,34116,34268,34420,34571,34723,34874,35026,35178,
	35329,35481,35633,35784,35936,36087,36239,36391,36542,36694,
	36846,36997,37149,37300,37452,37604,37755,37907,38059,38210,
	38362,38514,38665
    },
    {
	0,28,56,84,113,141,169,197,226,254,282,310,339,367,395,424,452,
	480,508,537,565,593,621,650,678,706,735,763,791,819,848,876,904,
	932,961,989,1017,1045,1074,1102,1130,1159,1187,1215,1243,1272,
	1300,1328,1356,1385,1413,1441,1470,1498,1526,1554,1583,1611,
	1639,1667,1696,1724,1752,1781,1809,1837,1865,1894,1922,1950,
	1978,2007,2035,2063,2091,2120,2148,2176,2205,2233,2261,2289,
	2318,2346,2374,2402,2431,2459,2487,2516,2544,2572,2600,2629,
	2657,2685,2713,2742,2770,2798,2827,2855,2883,2911,2940,2968,
	2996,3024,3053,3081,3109,3137,3166,3194,3222,3251,3279,3307,
	3335,3364,3392,3420,3448,3477,3505,3533,3562,3590,3618,3646,
	3675,3703,3731,3759,3788,3816,3844,3872,3901,3929,3957,3986,
	4014,4042,4070,4099,4127,4155,4183,4212,4240,4268,4297,4325,
	4353,4381,4410,4438,4466,4494,4523,4551,4579,4608,4636,4664,
	4692,4721,4749,4777,4805,4834,4862,4890,4918,4947,4975,5003,
	5032,5060,5088,5116,5145,5173,5201,5229,5258,5286,5314,5343,
	5371,5399,5427,5456,5484,5512,5540,5569,5597,5625,5654,5682,
	5710,5738,5767,5795,5823,5851,5880,5908,5936,5964,5993,6021,
	6049,6078,6106,6134,6162,6191,6219,6247,6275,6304,6332,6360,
	6389,6417,6445,6473,6502,6530,6558,6586,6615,6643,6671,6699,
	6728,6756,6784,6813,6841,6869,6897,6926,6954,6982,7010,7039,
	7067,7095,7124,7152,7180,7208
    },
};
